package com.example.demo.service;

import com.example.demo.entity.MongoDbFile;
import com.mongodb.DB;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.gridfs.GridFS;
import com.mongodb.gridfs.GridFSFile;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;

/**
 * @Description mongodb 把 mongoDBFile中的文件导出到 fs.files
 * @Author wangzi
 * @Date 2019/4/17 10:40
 */
@Service
public class MongoDBFileExport {

    @Autowired
    private MongoTemplate mongoTemplate;

    private static String MONGODBFILE = "mongoDbFile";

    private static String FSFILES = "fs.files";

    private static String FSCHUNKS = "fs.chunks";

    /**
     * @Author wangzi
     * @Description 查询idLis
     * @Date 2019/4/17 13:24
     **/
    public List<MongoDbFile> getObjectIds(String collName) {

        Document queryObject = new Document();

        Document fieldsObject = new Document();
        fieldsObject.put("id", true);

        Query query = new BasicQuery(queryObject, fieldsObject);
        List<MongoDbFile> ids = mongoTemplate.find(query, MongoDbFile.class, collName);
        return ids;
    }

    /**
     * @Author wangzi
     * @Description 查询fs.chunks fileIds
     * @Date 2019/4/17 13:24
     **/
    public List<MongoDbFile> getFlieIds() {

        Document queryObject = new Document();

        Document fieldsObject = new Document();
        fieldsObject.put("id", true);
        fieldsObject.put("filesId", true);

        Query query = new BasicQuery(queryObject);
        query.limit(3);
        List<MongoDbFile> ids = mongoTemplate.find(query, MongoDbFile.class, FSCHUNKS);
        return ids;
    }

    /**
     * @Author wangzi
     * @Description 比对重复id
     * @Date 2019/4/17 13:24
     **/
    public List<String> repaatIds(){
        //获取files
        List<MongoDbFile> files = getObjectIds(MONGODBFILE);
        //获取fsFiles
        List<MongoDbFile> fsFiles = getObjectIds(FSFILES);

        List<String> list = new ArrayList<>();
        //比对重复id
        for (MongoDbFile file : files) {
            for (MongoDbFile fs : fsFiles) {
                if (file.getId().equals(fs.getId())){
                    list.add(file.getId().toString());
                    System.out.println("重复id: " + file.getId().toString() + "---" + fs.getId().toString());
                }
            }
        }
        return list;
    }

    /**
     * @Author wangzi
     * @Description 比对重复files_id
     * @Date 2019/4/17 13:24
     **/
    public List<String> repaatFilesId(){
        //获取files
        List<MongoDbFile> files = getObjectIds(MONGODBFILE);

        List<MongoDbFile> filesIds = getFlieIds();

        List<String> list = new ArrayList<>();
        //比对重复id
        for (MongoDbFile file : files) {
            for (MongoDbFile fc : filesIds) {
                if (file.getId().equals(fc.getFilesId())){
                    list.add(file.getId().toString());
                    System.out.println("重复filesId: " + file.getId().toString() + "---" + fc.getFilesId().toString());
                }
            }
        }
        return list;
    }
    /**
     * @Author wangzi
     * @Description 转存文件
     * @Date 2019/4/17 13:54
     **/
    public List<String> saveToFile(List<MongoDbFile> mongoDbFiles){
        List<String> list = new ArrayList<>();
        for (MongoDbFile mongoDbFile : mongoDbFiles){
            InputStream ins = new ByteArrayInputStream(mongoDbFile.getContent().getData());
            String id = mongoDbFile.getId();
            // 将文件存储到mongodb中
            id = save(mongoDbFile, ins);
            System.out.println("文件：" + mongoDbFile.getName() + "保存完成...");
            list.add(id);
        }
        return list;
    }

    /**
     * @Author wangzi
     * @Description 查询mongofiles
     * @Date 2019/4/17 13:54
     **/
    public List<MongoDbFile> queryFile(int limit, int skip){

        Document queryObject = new Document();

        Query query = new BasicQuery(queryObject);
        query.limit(limit).skip(skip);
        List<MongoDbFile> files = mongoTemplate.find(query, MongoDbFile.class, MONGODBFILE);
        return files;
    }

    /**
     * @Author wangzi
     * @Description 最终整合方法 批量把mondbFile表里的文件转存到fs.file表
     * @Date 2019/4/17 14:43
     **/
    public List<String> finallyMethod(int limit){
        List<String> ids = new ArrayList<>();
        //获取重复id
        List<String> list = repaatIds();
        //获取重复filesId
        List<String> filesIdList = repaatFilesId();
        int skip = 0;
        while(true) {
            //获取指定数量文件
            List<MongoDbFile> mongoDbFiles = queryFile(1, 1);
            //剔除id重复的文件
            for (String id : list){
                for(int i=0; i<mongoDbFiles.size(); i++){
                    if (id.equals(mongoDbFiles.get(i).getId())){
                        mongoDbFiles.remove(i);
                    }
                }
            }
            if (mongoDbFiles == null || mongoDbFiles.size() <=0){
                break;
            }
            //转存查询出的文件
            List<String> objectIds = saveToFile(mongoDbFiles);
            ids.addAll(objectIds);
            skip += limit;
            if (skip == 300){
                return ids;
            }
            return ids;
        }
        return ids;
    }

    /**
     * @Author wangzi
     * @Description save
     * @Date 2019/4/17 17:25
     * @Param
     * @return
     **/
    public String save(MongoDbFile mongoDbFile, InputStream inputStream){
        //spring的gridFsTemplate操作模板并不支持自定义ID，所以采用以下驱动API接口写入
        DB db = getDb();
        GridFS gridFS= new GridFS(db,"fs");
        GridFSFile gridFSFile =  gridFS.createFile(inputStream);
        gridFSFile.put("_id", mongoDbFile.getId());
        gridFSFile.put("filename", mongoDbFile.getName());
        gridFSFile.put("contentType", mongoDbFile.getContentType());
        gridFSFile.save();
        return mongoDbFile.getId();
    }

    /**
     * @Author wangzi
     * @Description 创建mongoClient
     * @Date 2019/4/17 18:15
     **/

    public DB getDb(){
        //连接到MongoDB服务 如果是远程连接可以替换“localhost”为服务器所在IP地址
//        //ServerAddress()两个参数分别为 服务器地址 和 端口
        ServerAddress serverAddress1 = new ServerAddress("10.221.2.76",27017);
        ServerAddress serverAddress2 = new ServerAddress("10.221.2.77",27017);
        ServerAddress serverAddress3 = new ServerAddress("10.221.2.79",27017);
//        ServerAddress serverAddress4 = new ServerAddress("127.0.0.1",27017);
        List<ServerAddress> addrs = new ArrayList<ServerAddress>();
        addrs.add(serverAddress1);
        addrs.add(serverAddress2);
        addrs.add(serverAddress3);
//        addrs.add(serverAddress4);

//        MongoCredential.createScramSha1Credential()三个参数分别为 用户名 数据库名称 密码
        MongoCredential credential = MongoCredential.createScramSha1Credential("labor", "qlgh_app", "inspur123".toCharArray());
        List<MongoCredential> credentials = new ArrayList<MongoCredential>();
        credentials.add(credential);
        //通过连接认证获取MongoDB连接
        MongoClient mongoClient = new MongoClient(addrs,credentials);
        DB db = mongoClient.getDB("qlgh_app");
        return db;
    }

    public static void main(String[] args) {

        HashMap<Object, Object> map1 = new HashMap<>();
        map1.put("aa", "aa1");
        map1.put("bb", "bb");

        HashMap<Object, Object> map2 = new HashMap<>();
        map2.put("aa", "aa");
        map2.put("bb", "bb");

        HashSet<Map> set = new HashSet<>();
        set.add(map1);
        set.add(map2);

        System.out.println(set);

    }






}
